package it.com.chen.movieReleasesDB;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
import java.util.HashMap;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

//public class MovieScrollPane {

public class MovieScrollPane extends JPanel implements ListSelectionListener {
	private JLabel titleLabel;
	private JButton urlButton;
	private JLabel releaseDateLabel;

	private JList list;
	private JSplitPane splitPane;
	private String[] listNames;
	private JPanel infoPane;

	private HashMap<Integer, DBEntry> db;

	public MovieScrollPane(ProgramData programData) {

		db = programData.getDb();

		String[] listNames = new String[db.size()];
		for (int i = 0; i < db.size(); i++) {
			listNames[i] = db.get(i).getMovieTitle();
		}

		// Create the list of images and put it in a scroll pane.

		list = new JList(listNames);
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		list.setSelectedIndex(0);
		list.addListSelectionListener(this);

		JScrollPane listScrollPane = new JScrollPane(list);

		infoPane = new JPanel();
		infoPane.setLayout(new BoxLayout(infoPane, BoxLayout.Y_AXIS));
		infoPane.setBorder(BorderFactory.createTitledBorder(
				BorderFactory.createEtchedBorder(), "Movie",
				TitledBorder.DEFAULT_JUSTIFICATION,
				TitledBorder.DEFAULT_POSITION, new Font("Sans", 1, 13),
				Color.BLUE));

		JPanel row1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row1);
		row1.add(titleLabel = new JLabel(db.get(0).getMovieTitle()));
		Font fontTitle = new Font("Dialog", Font.PLAIN, 24);
		titleLabel.setFont(fontTitle);

		JPanel row7 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row7);
		JPanel row8 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row8);

		JPanel row2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row2);
		row2.add(releaseDateLabel = new JLabel("Release date = "
				+ db.get(0).getReleaseDate()
				+ "/"
				+ CalendarMonthManager
						.convertMonth(db.get(0).getReleaseMonth()) + "/"
				+ db.get(0).getReleaseYear()));
		Font font = new Font("Dialog", Font.PLAIN, 20);
		JPanel row3 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row3);
		urlButton = new JButton("Description");
		row3.add(urlButton);

		urlButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openURL(db.get(0).getDescriptionUrl());
			}
		});

		JPanel row4 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row4);
		JPanel row5 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row5);
		JPanel row6 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		infoPane.add(row6);

		releaseDateLabel.setFont(font);

		// Create a split pane with the two scroll panes in it.
		splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listScrollPane,
				infoPane);
		splitPane.setOneTouchExpandable(true);
		splitPane.setDividerLocation(275);

		// Provide minimum sizes for the two components in the split pane.
		Dimension minimumSize = new Dimension(300, 50);
		listScrollPane.setMinimumSize(minimumSize);
		infoPane.setMinimumSize(minimumSize);

		// Provide a preferred size for the split pane.
		splitPane.setPreferredSize(new Dimension(750, 550));
	}

	// Listens to the list
	public void valueChanged(ListSelectionEvent e) {
		JList list = (JList) e.getSource();
		updateLabel(
				list.getSelectedValue().toString(),
				"Release date = "
						+ db.get(list.getSelectedIndex()).getReleaseDate()
						+ "/"
						+ CalendarMonthManager.convertMonth(db.get(0)
								.getReleaseMonth()) + "/"
						+ db.get(0).getReleaseYear(), list.getSelectedIndex());
	}

	protected void updateLabel(String name, String releaseDate,
			final int selectedIndex) {
		titleLabel.setText(name);
		releaseDateLabel.setText(releaseDate);
		for (ActionListener al : urlButton.getActionListeners()) {
			urlButton.removeActionListener(al);
		}
		urlButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openURL(db.get(selectedIndex).getDescriptionUrl());
			}
		});
		// urlLabel.setText(url);
	}

	private static final String errMsg = "Error attempting to launch web browser";

	public static void openURL(String url) {
		String osName = System.getProperty("os.name");
		try {
			if (osName.startsWith("Mac OS")) {
				Class fileMgr = Class.forName("com.apple.eio.FileManager");
				Method openURL = fileMgr.getDeclaredMethod("openURL",
						new Class[] { String.class });
				openURL.invoke(null, new Object[] { url });
			} else if (osName.startsWith("Windows"))
				Runtime.getRuntime().exec(
						"rundll32 url.dll,FileProtocolHandler " + url);
			else { // assume Unix or Linux
				String[] browsers = { "firefox", "opera", "konqueror",
						"epiphany", "mozilla", "netscape" };
				String browser = null;
				for (int count = 0; count < browsers.length && browser == null; count++)
					if (Runtime.getRuntime()
							.exec(new String[] { "which", browsers[count] })
							.waitFor() == 0)
						browser = browsers[count];
				if (browser == null)
					throw new Exception("Could not find web browser");
				else
					Runtime.getRuntime().exec(new String[] { browser, url });
			}
		} catch (Exception e) {
			System.out.println(
					errMsg + ":\n" + e.getLocalizedMessage());
		}
	}

	public JSplitPane getSplitPane() {
		return splitPane;
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 */
	private static void createAndShowGUI() {
		ProgramData programData = FileDBReader.collectReleasedMovies();

		// Create and set up the window.
		JFrame frame = new JFrame("Blue ray releases");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		MovieScrollPane splitPaneDemo = new MovieScrollPane(programData);
		frame.getContentPane().add(splitPaneDemo.getSplitPane());

		// Display the window.
		frame.pack();
		frame.setVisible(true);
	}

	public static void main(String[] args) {
		// Schedule a job for the event-dispatching thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}

}
